package com.thunder.kocho.devaloka

import android.animation.ValueAnimator
import android.graphics.*
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
import android.view.animation.LinearInterpolator

class Devaloka(borderWidth: Float, cornerRadius: Float, color: Int, duration: Long) : Drawable(),
    Drawable.Callback, Animatable {

    private var mBorderPath = Path()
    private var mMatrix = Matrix()
    private var mPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    private val mColors = intArrayOf(
        Color.WHITE,
        color,
        Color.WHITE,
        color,
        Color.WHITE
    )
    private val mBorderWidth = borderWidth
    private val mCornerRadius = cornerRadius
    private val mDuration = duration

    private lateinit var mSweepGradient: SweepGradient
    private lateinit var mAnimator: ValueAnimator

    constructor(borderWidth: Float, cornerRadius: Float) : this(
        borderWidth,
        cornerRadius,
        Color.BLUE
    )

    constructor(borderWidth: Float, cornerRadius: Float, color: Int) : this(
        borderWidth,
        cornerRadius,
        color,
        3000
    )

    override fun draw(canvas: Canvas) {
        if (!bounds.isEmpty) {
            canvas.drawPath(mBorderPath, mPaint)
        }
    }

    override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
        super.setBounds(left, top, right, bottom)
        val l = bounds.left + mBorderWidth
        val t = bounds.top + mBorderWidth
        val r = bounds.right - mBorderWidth
        val b = bounds.bottom - mBorderWidth

        mBorderPath.moveTo((l + mCornerRadius), t)
        mBorderPath.lineTo((r - mCornerRadius), t)
        mBorderPath.quadTo(r, t, r, t + mCornerRadius)
        mBorderPath.lineTo(r, b - mCornerRadius)
        mBorderPath.quadTo(r, b, r - mCornerRadius, b)
        mBorderPath.lineTo(l + mCornerRadius, b)
        mBorderPath.quadTo(l, b, l, b - mCornerRadius)
        mBorderPath.lineTo(l, t + mCornerRadius)
        mBorderPath.quadTo(l, t, l + mCornerRadius, t)
        mBorderPath.close()

        mPaint.style = Paint.Style.STROKE
        mPaint.strokeWidth = mBorderWidth
        mSweepGradient = SweepGradient(bounds.width() / 2f, bounds.height() / 2f, mColors, null)
        mPaint.shader = mSweepGradient

        mAnimator = ValueAnimator.ofFloat(0f, 360f)
        mAnimator.addUpdateListener { animator ->
            mMatrix.setRotate(
                animator.animatedValue as Float,
                bounds.centerX().toFloat(),
                bounds.centerY().toFloat()
            )
            mSweepGradient.setLocalMatrix(mMatrix)
            invalidateSelf()
        }
        mAnimator.interpolator = LinearInterpolator()
        mAnimator.duration = mDuration
        mAnimator.repeatCount = -1
    }

    override fun start() {
        if (!this::mAnimator.isInitialized) {
            return
        }
        if (!mAnimator.isStarted && isVisible) {
            mAnimator.start()
        }
    }

    override fun stop() {
        if (!this::mAnimator.isInitialized) {
            return
        }
        if (mAnimator.isStarted) {
            mAnimator.end()
        }
    }

    override fun isRunning(): Boolean {
        return if (this::mAnimator.isInitialized) mAnimator.isRunning else false
    }

    override fun invalidateDrawable(who: Drawable) {
        invalidateSelf()
    }

    override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) {

    }

    override fun unscheduleDrawable(who: Drawable, what: Runnable) {

    }

    override fun setAlpha(alpha: Int) {

    }

    override fun setColorFilter(colorFilter: ColorFilter?) {

    }

    override fun getOpacity(): Int {
        return PixelFormat.TRANSLUCENT
    }
}